﻿#pragma once
#include "oatpp/parser/json/mapping/ObjectMapper.hpp"
#include "oatpp/web/server/api/ApiController.hpp"
#include "oatpp/web/mime/multipart/Multipart.hpp"

#include "oatpp/core/data/stream/FileStream.hpp"
#include "oatpp/core/macro/codegen.hpp"
#include "../util/FileUtil.h"
#include "../util/TextUtil.h"
#include "../config/SystemConfig.h"
#include "../dto/SimpleDto.h"
#include "../dto/FileDto.h"

#include OATPP_CODEGEN_BEGIN(ApiController)

class FileController : public oatpp::web::server::api::ApiController {
public:
	FileController(const std::shared_ptr<ObjectMapper>& objectMapper)
		: oatpp::web::server::api::ApiController(objectMapper)
	{}

	/**
	 * 文件上传
	 */
	ENDPOINT("POST", "/file/upload", uploadFile,
		REQUEST(std::shared_ptr<IncomingRequest>, request)) {

		oatpp::String content = request->readBodyToString();
		std::string str = content.getValue("");

		int pos = str.find("\r\n");
		std::string start_boundary = str.substr(0, pos);
		std::string end_boundary = start_boundary;

		int end = str.find("\r\n\r\n");
		std::string fileName = "";
		std::string extName = "";
		while (true)
		{
			// Content-Disposition: form-data; name="file"; filename="20210622105652_57252.jpeg"
			int new_pos = str.find("\r\n", pos + 2);
			if (new_pos == -1 || new_pos >= end)
			{
				break;
			}
			std::string line = str.substr(pos + 2, new_pos - pos - 2);
			if (line.find("Content-Disposition:") != -1)
			{
				int start = line.find("filename=\"");
				int stop = line.find("\"", start + strlen("filename=\""));
				if (start != -1 && stop != -1)
				{
					fileName = line.substr(start + strlen("filename=\""), stop - start);
					fileName = fileName.substr(0, fileName.length() - 1);
					std::vector<std::string> arr = TextUtil::get_mutable_instance().SplitString(fileName, '.');
					if (str.size() >= 2)
					{
						extName = arr[1];
					}
				}
				break;
			}
			pos = new_pos;
		}

		pos = str.find("\r\n\r\n");
		if (pos != -1)
		{
			str = str.substr(pos + 4);
		}
		pos = str.find(end_boundary.c_str());
		if (pos != -1)
		{
			str = str.substr(0, pos);
			if (str.at(str.length() - 2) == 0x0d && str.at(str.length() - 1) == 0x0a)
			{
				str = str.substr(0, str.length() - 2);
			}
		}

		// 文件名称
		std::string uid = TextUtil::get_mutable_instance().GetGuid();
		std::string new_name = uid + "." + extName;
		// 保存路径
		std::string path = FileUtil::GetAppPath("file/");
		FileUtil::Mkdirs(path);
		path = path + new_name;
		// 保存文件
		FileUtil::Write(path, str);
		// 返回地址
		std::string url = SystemConfig::get_mutable_instance().GetLocalConf().GetFileUrl(new_name);

		// 文件信息
		auto file = FileVo::createShared();
		file->id = uid;
		file->url = url;
		file->name = fileName;

		// 返回操作结果
		auto result = FileDto::createShared();
		result->error = 0;
		result->description = "success";
		result->value = file;
		return createDtoResponse(Status::CODE_200, result);
	}

	/*
	* 文件下载
	*/
	ENDPOINT("GET", "/file/download", downloadFile,
		QUERY(String, name)) {
		// 返回操作结果
		auto result = AlarmListDto::createShared();
		result->error = -1;
		result->description = "服务器内部错误!";

		// 获取文件路径
		std::string path = FileUtil::GetAppPath("file/" + name);
		if (!FileUtil::Exists(path))
		{
			result->description = "文件不存在!";
			return createDtoResponse(Status::CODE_200, result);
		}

		// 返回文件内容
		std::string content = FileUtil::Read(path);
		return ResponseFactory::createResponse(Status::CODE_200, content);
	}
};

#include OATPP_CODEGEN_END(ApiController)